package com.meis.widget.photodrag;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.Component;

/**
 * Created by wenshi on 2018/5/18.
 * Description
 */
public class PhotoDragHelper implements OnPhotoDragListener {
    private static final int DURATION = 200;
    private static final int DRAG_SLOP_HEIGHT = 320;
    protected int mDragSlopHeight = DRAG_SLOP_HEIGHT;
    protected int mDuration = DURATION;

    /**
     * 拖动释放的动画
     */
    protected AnimatorValue mBackOrExitAnimator;
    private OnDragListener mListener;

    @Override
    public boolean isAnimationRunning() {
        return mBackOrExitAnimator != null && mBackOrExitAnimator.isRunning();
    }

    @Override
    public void onDrag(float dy) {
        if (mListener != null) {
            Component dragView = mListener.getDragView();
            if (dragView != null) {
                float currentY = dragView.getTranslationY();
                float finalY = currentY + dy;
                dragView.setTranslationY(finalY);
                setAlpha(finalY);
            }
        }
    }

    @Override
    public void onRelease() {
        if (mListener != null) {
            Component dragView = mListener.getDragView();
            if (dragView != null) {
                float from = dragView.getTranslationY();
                final boolean isExit = Math.abs(from) > mDragSlopHeight;
                float to = isExit ? ((from > 0) ? dragView.getHeight() : -dragView.getHeight()) : 0;
                endAnimation();
                mBackOrExitAnimator = new AnimatorValue();
                mBackOrExitAnimator.setDuration(mDuration);
                mBackOrExitAnimator.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
                    @Override
                    public void onUpdate(AnimatorValue animatorValue, float v) {
                        float animatedValue = from + (to - from) * v;
                        dragView.setTranslationY(animatedValue);
                        setAlpha(animatedValue);
                    }
                });
                mBackOrExitAnimator.setStateChangedListener(new Animator.StateChangedListener() {
                    @Override
                    public void onStart(Animator animator) {

                    }

                    @Override
                    public void onStop(Animator animator) {

                    }

                    @Override
                    public void onCancel(Animator animator) {

                    }

                    @Override
                    public void onEnd(Animator animator) {
                        mListener.onAnimationEnd(isExit);
                    }

                    @Override
                    public void onPause(Animator animator) {

                    }

                    @Override
                    public void onResume(Animator animator) {

                    }
                });
                mBackOrExitAnimator.start();
            }
        }
    }

    @Override
    public Component getDragView() {
        return mListener == null ? null : mListener.getDragView();
    }


    private void setAlpha(float offsetY) {
        float allFadeY = mDragSlopHeight * 2;
        float offsetTranslationY = Math.abs(offsetY);
        if (offsetTranslationY > allFadeY) {
            offsetTranslationY = allFadeY;
        }
        if (mListener != null) {
            mListener.onAlpha(1 - offsetTranslationY / allFadeY);
        }
    }

    protected void endAnimation() {
        if (null != mBackOrExitAnimator && mBackOrExitAnimator.isRunning()) {
            mBackOrExitAnimator.cancel();
        }
    }

    public PhotoDragHelper setDragSlopHeight(int dragSlopHeight) {
        mDragSlopHeight = dragSlopHeight;
        return this;
    }

    public PhotoDragHelper setDuration(int duration) {
        mDuration = duration;
        return this;
    }

    public PhotoDragHelper setOnDragListener(OnDragListener listener) {
        this.mListener = listener;
        return this;
    }

    public interface OnDragListener {
        void onAlpha(float alpha);

        /**
         * 获取拖拽view
         *
         * @return Component
         */
        Component getDragView();

        /**
         * 动画结束
         *
         * @param slop true you can finish current ability
         */
        void onAnimationEnd(boolean slop);
    }
}
